/**
 * ReportGear(2011)
 */
package com.reportgear.report.view.grid.editor.impl;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import com.reportgear.core.swing.layout.LayoutHelper;
import com.reportgear.core.swing.pane.base.EditorPane;
import com.reportgear.core.swing.pane.base.JBaseDialog;
import com.reportgear.report.core.api.idname.IdName;
import com.reportgear.report.data.datasource.JsDataSource;
import com.reportgear.report.data.datasource.JsDataSourceFactory;
import com.reportgear.report.model.cell.Cell;
import com.reportgear.report.model.cell.value.JsDataFieldObject;
import com.reportgear.report.view.grid.Grid;
import com.reportgear.report.view.grid.editor.AbstractCellEditor;
import com.sot.core.util.StringUtils;

/**
 * JsDataFieldObject 编辑器
 * 
 * @version 1.0 2011-7-27
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class JsDataFieldObjectEditor extends AbstractCellEditor {
	private JsDataFieldObject value;

	@Override
	public Component getCellEditorComponent(Grid grid, Cell cell) {
		JsDataFieldObjectEditPane editorPane = new JsDataFieldObjectEditPane();

		editorPane.populate((JsDataFieldObject) cell.getValue());

		if (editorPane.showDialog(grid) == JBaseDialog.RESULT_OK) {
			this.value = editorPane.update();
		}

		return null;
	}

	@Override
	public Object getCellEditorValue() {
		return this.value;
	}

	private static class JsDataFieldObjectEditPane extends EditorPane<JsDataFieldObject> {
		/**
		 * UID
		 */
		private static final long serialVersionUID = 7066129706219244594L;
		private JsDataFieldObject value;
		private JComboBox cbxDataSource;
		private TypePane typePane;
		private JCheckBox chkExpand;

		private JsDataFieldObjectEditPane() {
			this.setBorder(BorderFactory.createEtchedBorder());
			this.setLayout(new GridBagLayout());
			this.cbxDataSource = new JComboBox(JsDataSourceFactory.INSTANCE.getDataSourceList().toArray(new IdName[0]));
			this.cbxDataSource.addActionListener(new ActionListener() {

				@SuppressWarnings("unchecked")
				@Override
				public void actionPerformed(ActionEvent e) {
					JComboBox cbx = (JComboBox) e.getSource();

					Object selected = cbx.getSelectedItem();
					if (selected != null) {
						IdName<String> ds = (IdName<String>) cbx.getSelectedItem();
						JsDataSource jds = JsDataSourceFactory.INSTANCE.getDataSource(ds.getId());
						typePane.setFields(jds.getFields());
					}
				}
			});
			this.cbxDataSource.setPreferredSize(new Dimension(300, 24));

			this.add(new JLabel("数据源", SwingConstants.LEFT), LayoutHelper.newGridBagConstraints(0, 0, 1, 1));
			this.add(this.cbxDataSource, LayoutHelper.newGridBagConstraints(1, 0, 1, 1));
			this.typePane = new TypePane();
			this.add(this.typePane, LayoutHelper.newGridBagConstraints(0, 1, 2, 1));
			this.chkExpand = new JCheckBox("扩展");
			this.add(this.chkExpand, LayoutHelper.newGridBagConstraints(0, 2, 1, 1));

		}

		@Override
		public void populate(JsDataFieldObject value) {
			this.value = value;

			this.chkExpand.setSelected(value.isExpand());

			String id = value.getDataSourceId();
			if (StringUtils.isEmpty(id)) {
				return;
			}

			for (int i = 0, size = this.cbxDataSource.getItemCount(); i < size; i++) {
				@SuppressWarnings("unchecked")
				IdName<String> item = (IdName<String>) cbxDataSource.getItemAt(i);

				if (id.equals(item.getId())) {
					cbxDataSource.setSelectedIndex(i);

					break;
				}
			}

			this.typePane.populate(value);
		}

		@Override
		public int showDialog(Component owner) {
			return this.showDialog(SwingUtilities.getWindowAncestor(owner), "履历信息", 460, 220);
		}

		@Override
		public JsDataFieldObject update() {
			@SuppressWarnings("unchecked")
			IdName<String> item = (IdName<String>) this.cbxDataSource.getSelectedItem();

			if (item != null) {
				this.value.setDataSourceId(item.getId());
				this.value.setDataSourceCaption(item.getName());
			}

			this.typePane.update(this.value);

			this.value.setExpand(this.chkExpand.isSelected());
			return this.value;
		}
	}

	/**
	 * 类型面板
	 * 
	 */
	private static class TypePane extends JPanel {
		/**
		 * UID
		 */
		private static final long serialVersionUID = -3557505032932953835L;
		private JRadioButton rbtnNormal;
		private JRadioButton rbtnPhoto;
		private JRadioButton rbtnFormula;

		private JLabel lblField;
		private JComboBox cbxField;
		private JLabel lblFormula;
		private JTextField txtFormula;

		private TypePane() {
			this.initComponents();
		}

		/**
		 * @param fields
		 */
		public void setFields(List<IdName<String>> fields) {
			DefaultComboBoxModel model = (DefaultComboBoxModel) cbxField.getModel();
			model.removeAllElements();

			for (IdName<String> idn : fields) {
				model.addElement(idn);
			}
		}

		private void initComponents() {
			this.setLayout(new BorderLayout());

			JPanel paneBtns = new JPanel();
			this.add(paneBtns, BorderLayout.NORTH);

			ButtonGroup bg = new ButtonGroup();
			this.rbtnNormal = new JRadioButton("字段", true);
			this.rbtnNormal.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					lblField.setVisible(true);
					cbxField.setVisible(true);
					lblFormula.setVisible(false);
					txtFormula.setVisible(false);
				}
			});

			paneBtns.add(this.rbtnNormal);
			bg.add(this.rbtnNormal);

			this.rbtnPhoto = new JRadioButton("相片");
			this.rbtnPhoto.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					lblField.setVisible(true);
					cbxField.setVisible(true);
					lblFormula.setVisible(false);
					txtFormula.setVisible(false);
				}
			});
			paneBtns.add(this.rbtnPhoto);
			bg.add(this.rbtnPhoto);

			this.rbtnFormula = new JRadioButton("公式");
			this.rbtnFormula.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					lblFormula.setVisible(true);
					txtFormula.setVisible(true);
					lblField.setVisible(false);
					cbxField.setVisible(false);
				}
			});
			paneBtns.add(this.rbtnFormula);
			bg.add(this.rbtnFormula);

			JPanel content = new JPanel();
			content.setLayout(new FlowLayout(FlowLayout.LEFT));

			this.lblField = new JLabel("字段");
			content.add(this.lblField);
			this.cbxField = new JComboBox();
			this.cbxField.setPreferredSize(new Dimension(300, 24));
			content.add(cbxField);

			this.lblFormula = new JLabel("公式");
			this.lblFormula.setVisible(false);
			content.add(this.lblFormula);
			this.txtFormula = new JTextField();
			this.txtFormula.setPreferredSize(new Dimension(300, 24));
			this.txtFormula.setVisible(false);
			content.add(this.txtFormula);

			this.add(content, BorderLayout.CENTER);
		}

		private void populate(JsDataFieldObject value) {
			int type = value.getType();

			if (type == JsDataFieldObject.TYPE_FORMULA) {
				this.lblFormula.setVisible(true);
				this.txtFormula.setVisible(true);
				this.lblField.setVisible(false);
				this.cbxField.setVisible(false);
				this.rbtnFormula.setSelected(true);
				this.txtFormula.setText(value.getFormula());
			} else {
				this.lblField.setVisible(true);
				this.cbxField.setVisible(true);
				this.lblFormula.setVisible(false);
				this.txtFormula.setVisible(false);

				if (type == JsDataFieldObject.TYPE_PHOTO) {
					this.rbtnPhoto.setSelected(true);
				} else {
					this.rbtnNormal.setSelected(true);
				}

				String id = value.getField();
				if (StringUtils.isEmpty(id)) {
					return;
				}

				for (int i = 0, size = this.cbxField.getItemCount(); i < size; i++) {
					@SuppressWarnings("unchecked")
					IdName<String> item = (IdName<String>) cbxField.getItemAt(i);

					if (id.equals(item.getId())) {
						cbxField.setSelectedIndex(i);
						break;
					}
				}
			}
		}

		private void update(JsDataFieldObject value) {
			if (this.rbtnFormula.isSelected()) {
				value.setType(JsDataFieldObject.TYPE_FORMULA);
				value.setFormula(this.txtFormula.getText().trim());
			} else {
				@SuppressWarnings("unchecked")
				IdName<String> item = (IdName<String>) this.cbxField.getSelectedItem();

				if (item != null) {
					value.setField(item.getId());
					value.setFieldCaption(item.getName());
				}

				if (this.rbtnNormal.isSelected()) {
					value.setType(JsDataFieldObject.TYPE_NORMAL);
				} else {
					value.setType(JsDataFieldObject.TYPE_PHOTO);
				}
			}
		}
	}
}
